﻿using rmTest.Common.ConstUtil;
using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
using System.Data.SqlClient;
using rmTest.Common.ModelUtil;
using rmTest.Common.AttrUtil;
using System.Linq;
using System.Reflection;
using System.Data;
using rmTest.Common.ExtensionUtil;
using System.Linq.Expressions;
using rmTest.Common.CacheUtil;
using DemormTest.Common.ExtensionUtil;

namespace rmTest.Common.DataBaseUtil
{
    public static class SqlHelper
    {
        /// <summary>
        /// 将数据库操作封装成委托，难度五颗星喔
        /// </summary>
        /// <param name="cmdText">执行命令的语句</param>
        /// <param name="connectionString">数据库链接字符串</param>
        /// <param name="action">委托</param>
        /// <param name="parameters">传入参数</param>
        private static void ExcuteSql(string cmdText, string connectionString, Action<SqlCommand> action, params SqlParameter[] parameters)
        {
            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                conn.Open();
                SqlCommand command = new SqlCommand(cmdText, conn);
                if (parameters.Length > 0)
                    command.Parameters.AddRange(parameters);
                action(command);
            }
        }

        /// <summary>
        /// 默认链接字符串
        /// </summary>
        /// <param name="cmdText"></param>
        /// <param name="action"></param>
        /// <param name="parameters"></param>
        private static void ExcuteSql(string cmdText, Action<SqlCommand> action, params SqlParameter[] parameters)
        {
            ExcuteSql(cmdText, ConfigurationArgs.DbConnection, action, parameters);
        }

        /// <summary>
        /// 将数据库操作封装成泛型+委托，带返回值，难度五颗星喔
        /// </summary>
        /// <param name="cmdText">执行命令的语句</param>
        /// <param name="connectionString">数据库链接字符串</param>
        /// <param name="action">委托</param>
        /// <param name="parameters">传入参数</param>
        private static OutT ExcuteSql<OutT>(string cmdText, string connectionString, Func<SqlCommand, OutT> func, params SqlParameter[] parameters)
        {
            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                conn.Open();
                SqlCommand command = new SqlCommand(cmdText, conn);
                if (parameters.Length > 0)
                    command.Parameters.AddRange(parameters);
                return func(command);
            }
        }
        /// <summary>
        /// 执行数据库，将数据库连接字符串默认
        /// </summary>
        /// <typeparam name="OutT"></typeparam>
        /// <param name="cmdText"></param>
        /// <param name="func"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        private static OutT ExcuteSql<OutT>(string cmdText, Func<SqlCommand, OutT> func, params SqlParameter[] parameters)
        {
            return ExcuteSql(cmdText, ConfigurationArgs.DbConnection, func, parameters);
        }

        /// <summary>
        /// 通过主键删除数据，运用泛型封装的方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public static int Delete<T>(object id) where T : BaseModel
        {
            Func<SqlCommand, int> func = x => { return x.ExecuteNonQuery(); };
            int iexcute = ExcuteSql(InitDeleteSql<T>(), func, new SqlParameter("1", id));
            return iexcute;
        }

        /// <summary>
        /// 通过模型更新数据，更新数据到数据库，运行委托方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public static int UpdateDataByModel<T>(T t) where T : BaseModel
        {
            List<object> values = new List<object>();
            string sql = InitUpdateSqlByT<T>(t, out values);
            List<SqlParameter> sqlParameters = new List<SqlParameter>();
            for (int i = 0; i < values.Count; i++)
            {
                sqlParameters.Add(new SqlParameter((i + 1).ToString(), values[i]));
            }
            Func<SqlCommand, int> func = x => { return x.ExecuteNonQuery(); };
            return ExcuteSql(sql, func, sqlParameters.ToArray());
        }

        /// <summary>
        /// 通过模型新增数据，插入数据到数据库，运用泛型和委托方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public static int InsertDataByModel<T>(T t) where T : BaseModel
        {
            List<object> values = new List<object>();
            string sql = InitInsertSqlByT<T>(t, out values);
            List<SqlParameter> sqlParameters = new List<SqlParameter>();
            for (int i = 0; i < values.Count; i++)
            {
                sqlParameters.Add(new SqlParameter((i + 1).ToString(), values[i]));
            }

            Func<SqlCommand, int> func = x => { return x.ExecuteNonQuery(); };
            return ExcuteSql(sql, func, sqlParameters.ToArray());
        }
        /// <summary>
        /// 查询所有数据列表，运用泛型方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static List<T> GetAllDataList<T>() where T : BaseModel, new()
        {
            string sql = InitSqlByT<T>();
            Func<SqlCommand, List<T>> func = x =>
            {
                List<T> list = new List<T>();
                #region datareader

                SqlDataReader reader = x.ExecuteReader();
                while (reader.Read())
                {
                    T t = InitModelByReder<T>(reader);
                    list.Add(t);
                }
                reader.Close();
                #endregion

                #region dataset 
                //SqlDataAdapter adapter = new SqlDataAdapter(x);
                //DataSet dataSet = new DataSet();
                //adapter.Fill(dataSet);
                //if (dataSet != null && dataSet.Tables.Count > 0 && dataSet.Tables[0].Rows.Count > 0)
                //{
                //    foreach (DataRow dataRow in dataSet.Tables[0].Rows)
                //    {
                //        Func<DataRow, T> expr = dataRow.ToExpression<T>();
                //        T t = expr.Invoke(dataRow);
                //        list.Add(t);
                //    }
                //}
                #endregion

                return list;
            };
            return ExcuteSql(sql, func);
        }

        /// <summary>
        /// 通过主键获取某条数据，泛型改写方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T Get<T>(object id) where T : BaseModel, new()
        {
            List<T> list = new List<T>();
            string sql = InitSqlByT<T>(false);
            SqlParameter parameter = new SqlParameter("1", id);
            ExcuteSql(sql, ConfigurationArgs.DbConnection, new Action<SqlCommand>(x =>
            {
                SqlDataReader reader = x.ExecuteReader(CommandBehavior.CloseConnection);
                while (reader.Read())
                {
                    T t = InitModelByReder<T>(reader);
                    list.Add(t);
                }
                reader.Close();
            }), parameter);
            return list.FirstOrDefault();
        }
        /// <summary>
        /// 通过表达式目录树，将dataReder装进模型，进行验证
        /// 并使用泛型缓存，缓存解析得到的表达式目录树
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <param name="reader"></param>
        /// <param name="type"></param>
        private static T InitModelByReder<T>(SqlDataReader reader) where T : BaseModel, new()
        {
            Func<SqlDataReader, T> expr = reader.ToExpression<T>();
            //if (FuncCache<SqlDataReader, T>._FUNC != null)
            //{
            //    expr = FuncCache<SqlDataReader, T>._FUNC;
            //}
            //else
            //{
            //    expr = InitFunc<T>(reader);
            //    FuncCache<SqlDataReader, T>._FUNC = expr;
            //}
            T t = expr.Invoke(reader);
            return t;
        }

        /// <summary>
        /// 使用表达式目录树，将SqlDataReader转成模型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="reader"></param>
        /// <returns></returns>
        private static Func<SqlDataReader, T> InitFunc<T>(SqlDataReader reader) where T : BaseModel
        {
            ParameterExpression parameterExpression = Expression.Parameter(typeof(SqlDataReader), "r");
            MethodInfo methodInfoGet = typeof(SqlDataReader).GetMethod("get_Item", new Type[] { typeof(string) });//定义一个参数 get_Item
            MethodInfo methodInfoAsTo = typeof(ObjectExtensions).GetMethod("ConvertToTheType", new Type[] { typeof(Object) });

            List<MemberBinding> memberBindings = new List<MemberBinding>();

            foreach (var property in typeof(T).GetProperties().Where(o => o.CanWrite))
            {
                string name = property.GetMemberInfoDisplayValue();//获取属性对应的数据表字段
                ModelBaseValidateAttribute modelAttr = property.GetCustomAttribute<ModelBaseValidateAttribute>();//获取属性的特性
                if (modelAttr == null || !modelAttr.Ignored)//无特性值为空或者表示不是数据表忽略字段时
                {
                    ConstantExpression constant = Expression.Constant(name);// 定义一个常量表达式，值为 数据表属性名
                                                                            //调用方法 get_Item
                    MethodCallExpression callGet_Item = Expression.Call(parameterExpression, methodInfoGet, constant);//
                    //找到静态泛型方法Asto()
                    MethodInfo makeGenericMethod = methodInfoAsTo.MakeGenericMethod(new Type[] { property.PropertyType });
                    MethodCallExpression call = Expression.Call(null, makeGenericMethod, new Expression[] { callGet_Item });
                    //初始化
                    MemberAssignment bing = Expression.Bind(property, call);
                    memberBindings.Add(bing);
                }
            }

            MemberInitExpression memberInit = Expression.MemberInit(Expression.New(typeof(T)), memberBindings.ToArray());
            Expression<Func<SqlDataReader, T>> expression = Expression.Lambda<Func<SqlDataReader, T>>
            (
                memberInit,
                new ParameterExpression[] { parameterExpression }
            );
            return expression.Compile();
        }


        private static Func<SqlDataReader, T> InitFunc2<T>(SqlDataReader reader)
        {
            ParameterExpression parameter = Expression.Parameter(typeof(SqlDataReader), "reader");//
            List<MemberBinding> binds = new List<MemberBinding>();
            foreach (var property in typeof(T).GetProperties())
            {
                if (property == null || !property.CanWrite) continue;
                string name = property.GetMemberInfoDisplayValue();
                ModelBaseValidateAttribute modelAttr = property.GetCustomAttribute<ModelBaseValidateAttribute>();
                if (modelAttr == null || !modelAttr.Ignored)
                {
                    for (int i = 0; i < reader.FieldCount; i++)
                    {
                        string columnName = reader.GetName(i);
                        if (name == columnName)
                        {
                            //MethodInfo methodInfo = MethodBase.GetCurrentMethod() as MethodInfo;//获取当前执行的方法
                            MethodInfo mInfo = reader.GetType().GetMethod("GetFieldValue").MakeGenericMethod(property.PropertyType);
                            MethodCallExpression call = Expression.Call(parameter, mInfo, Expression.Constant(i));
                            MemberAssignment bind = Expression.Bind(property, call);
                            binds.Add(bind);
                            break;
                        }
                    }
                }
                else
                {

                }
            }
            MemberInitExpression init = Expression.MemberInit(Expression.New(typeof(T)), binds.ToArray());
            Func<SqlDataReader, T> expr = Expression.Lambda<Func<SqlDataReader, T>>(init, parameter).Compile();
            return expr;
        }

        /// <summary>
        /// 可以使用，解决了可为空类型处理，但是没法使用缓存，
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="reader"></param>
        /// <returns></returns>
        private static Func<SqlDataReader, T> InitFunc4<T>(SqlDataReader reader)
        {
            ParameterExpression parameter = Expression.Parameter(typeof(SqlDataReader), "reader");//
            List<MemberBinding> binds = new List<MemberBinding>();
            foreach (var property in typeof(T).GetProperties())
            {
                if (property == null || !property.CanWrite) continue;
                string name = property.GetMemberInfoDisplayValue();
                ModelBaseValidateAttribute modelAttr = property.GetCustomAttribute<ModelBaseValidateAttribute>();
                if (modelAttr == null || !modelAttr.Ignored)
                {
                    for (int i = 0; i < reader.FieldCount; i++)
                    {
                        string columnName = reader.GetName(i);
                        if (name == columnName)
                        {
                            Expression expression = Expression.Constant(reader.GetValue(i) is DBNull ? null : reader.GetValue(i), property.PropertyType);
                            MemberAssignment bind = Expression.Bind(property, expression);
                            binds.Add(bind);
                            break;
                        }
                    }
                }
                else
                {

                }
            }
            MemberInitExpression init = Expression.MemberInit(Expression.New(typeof(T)), binds.ToArray());
            Func<SqlDataReader, T> expr = Expression.Lambda<Func<SqlDataReader, T>>(init, parameter).Compile();
            return expr;
        }

        /// <summary>
        /// 可以使用，但是没有处理可为空类型，比如DateTime?
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="reader"></param>
        /// <returns></returns>
        private static Func<SqlDataReader, T> InitFunc3<T>(SqlDataReader reader)
        {
            ParameterExpression parameter = Expression.Parameter(typeof(SqlDataReader), "reader");//
            List<MemberBinding> binds = new List<MemberBinding>();
            foreach (var property in typeof(T).GetProperties())
            {
                string name = property.GetMemberInfoDisplayValue();
                if (property == null || !property.CanWrite) continue;
                ModelBaseValidateAttribute modelAttr = property.GetCustomAttribute<ModelBaseValidateAttribute>();
                if (modelAttr == null || !modelAttr.Ignored)
                {
                    for (int i = 0; i < reader.FieldCount; i++)
                    {
                        string columnName = reader.GetName(i);
                        if (name == columnName)
                        {
                            MethodInfo mInfo = reader.GetType().GetMethod("GetFieldValue").MakeGenericMethod(property.PropertyType);
                            MethodCallExpression call = Expression.Call(parameter, mInfo, Expression.Constant(i));
                            MemberAssignment bind = Expression.Bind(property, call);
                            binds.Add(bind);
                            break;
                        }
                    }
                }
                else
                {

                }
            }
            MemberInitExpression init = Expression.MemberInit(Expression.New(typeof(T)), binds.ToArray());
            Func<SqlDataReader, T> expr = Expression.Lambda<Func<SqlDataReader, T>>(init, parameter).Compile();
            return expr;
        }


        /// <summary>
        /// 将dataReder装进模型，没有使用表达式目录树
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <param name="reader"></param>
        /// <param name="type"></param>
        private static T InitModelByReder2<T>(SqlDataReader reader) where T : BaseModel
        {
            Type type = typeof(T);
            T t = Activator.CreateInstance<T>();
            PropertyInfo[] propertys = type.GetProperties();
            foreach (PropertyInfo property in propertys)
            {
                //通过数据库查询，给字段赋值
                if (property.IsDefined(typeof(ModelBaseValidateAttribute), true))
                {
                    ModelBaseValidateAttribute modelAttr = property.GetCustomAttribute<ModelBaseValidateAttribute>();
                    if (!modelAttr.Ignored)
                    {
                        string name = property.GetMemberInfoDisplayValue();
                        property.SetValue(t, reader[name] is DBNull ? null : reader[name]);
                    }
                }
                else
                {
                    property.SetValue(t, reader[property.Name] is DBNull ? null : reader[property.Name]);
                }
            }
            InitSetEnumValue(t, propertys);
            return t;
        }

        private static void InitSetEnumValue<T>(T t, PropertyInfo[] propertys) where T : BaseModel
        {
            foreach (PropertyInfo property in propertys)
            {
                //通过数据库查询，给字段赋值后，将需要映射的字段赋值
                if (property.IsDefined(typeof(EnumMapAttribute), true))
                {
                    EnumMapAttribute mapAttr = property.GetCustomAttribute<EnumMapAttribute>();
                    if (!string.IsNullOrEmpty(mapAttr.DataField) && mapAttr.EnumType != null)
                    {
                        //获取属性数据库数值
                        PropertyInfo dataProperty = propertys.FirstOrDefault(x => x.Name == mapAttr.DataField);
                        if (dataProperty != null)
                        {
                            var dataValue = dataProperty.GetValue(t);
                            if (dataValue != null)
                            {
                                string dataname = string.Empty;
                                int iDataValue = int.MinValue;
                                if (int.TryParse(dataValue.ToString(), out iDataValue))
                                {
                                    foreach (var item in Enum.GetValues(mapAttr.EnumType))
                                    {
                                        if ((int)item == iDataValue)
                                        {
                                            dataname = item.ToString();

                                            FieldInfo field = mapAttr.EnumType.GetField(dataname);
                                            if (field.IsDefined(typeof(DisplayBaseAttribute), true))
                                            {
                                                DisplayBaseAttribute attribute = (DisplayBaseAttribute)field.GetCustomAttribute(typeof(DisplayBaseAttribute), true);
                                                dataname = attribute.GetDisplayName();
                                            }

                                            property.SetValue(t, dataname);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }


        #region old function

        /// <summary>
        /// 通过模型新增数据，插入数据到数据库，old
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public static int InsertDataByModel2<T>(T t) where T : BaseModel
        {
            int iexcute = 0;
            using (SqlConnection conn = new SqlConnection(ConfigurationArgs.DbConnection))
            {
                List<object> values = new List<object>();
                string sql = InitInsertSqlByT<T>(t, out values);
                SqlCommand command = new SqlCommand(sql, conn);
                for (int i = 0; i < values.Count; i++)
                {
                    command.Parameters.Add(new SqlParameter((i + 1).ToString(), values[i]));
                }
                conn.Open();
                iexcute = command.ExecuteNonQuery();
            }
            return iexcute;
        }

        /// <summary>
        /// 通过模型更新数据，更新数据到数据库，old
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public static int UpdateDataByModel2<T>(T t) where T : BaseModel
        {
            int iexcute = 0;
            using (SqlConnection conn = new SqlConnection(ConfigurationArgs.DbConnection))
            {
                List<object> values = new List<object>();
                string sql = InitUpdateSqlByT<T>(t, out values);
                SqlCommand command = new SqlCommand(sql, conn);
                for (int i = 0; i < values.Count; i++)
                {
                    command.Parameters.Add(new SqlParameter((i + 1).ToString(), values[i]));
                }
                conn.Open();
                iexcute = command.ExecuteNonQuery();
            }
            return iexcute;
        }

        /// <summary>
        /// 通过主键删除数据，old
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public static int Delete2<T>(object id) where T : BaseModel
        {
            int iexcute = 0;
            using (SqlConnection conn = new SqlConnection(ConfigurationArgs.DbConnection))
            {
                List<object> values = new List<object>();
                string sql = InitDeleteSql<T>();
                SqlCommand command = new SqlCommand(sql, conn);
                command.Parameters.Add(new SqlParameter("1", id));
                conn.Open();
                iexcute = command.ExecuteNonQuery();
            }
            return iexcute;
        }

        /// <summary>
        /// 通过主键获取某条数据，old
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T Get2<T>(object id) where T : BaseModel, new()
        {
            List<T> list = new List<T>();

            using (SqlConnection conn = new SqlConnection(ConfigurationArgs.DbConnection))
            {
                string sql = InitSqlByT<T>(false);
                SqlCommand command = new SqlCommand(sql, conn);
                command.Parameters.Add(new SqlParameter("1", id));
                conn.Open();
                SqlDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection);
                command.Parameters.Clear();
                if (reader.Read())
                {
                    T t = InitModelByReder<T>(reader);
                    list.Add(t);
                }
                return list.FirstOrDefault();
            }
        }

        /// <summary>
        /// 查询所有数据列表，old
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static List<T> GetAllDataList2<T>() where T : BaseModel, new()
        {
            List<T> list = new List<T>();
            using (SqlConnection conn = new SqlConnection(ConfigurationArgs.DbConnection))
            {
                string sql = InitSqlByT<T>();
                SqlCommand command = new SqlCommand(sql, conn);
                conn.Open();
                SqlDataReader reader = command.ExecuteReader();
                while (reader.Read())
                {
                    T t = InitModelByReder<T>(reader);
                    list.Add(t);
                }
                return list;
            }
        }

        #endregion

        #region InitSql

        /// <summary>
        /// 拼装插入数据的SQL
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        private static string InitDeleteSql<T>() where T : BaseModel
        {
            string sql = string.Empty;
            //加载模型类型
            Type type = typeof(T);
            //获取类型的属性 TableName 
            string tableName = Activator.CreateInstance<T>().GetModelDisplayValue();
            string condition = string.Empty;
            //获取类型的所有字段，库对应的所有字段
            PropertyInfo[] propertys = type.GetProperties();
            foreach (PropertyInfo property in propertys)
            {
                if (property.IsDefined(typeof(ModelBaseValidateAttribute), true))
                {
                    ModelBaseValidateAttribute modelAttr = property.GetCustomAttribute<ModelBaseValidateAttribute>();
                    if (modelAttr.IsPrimaryKey)//如果是主键，将作为条件过滤
                    {
                        string name = property.GetMemberInfoDisplayValue();
                        condition = "[" + name + "]=@1";
                    }
                }
            }
            sql = string.Format("DELETE FROM [dbo].[{0}] where {1}", tableName, condition);
            return sql;
        }

        /// <summary>
        /// 拼装插入数据的SQL
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        private static string InitUpdateSqlByT<T>(T t, out List<object> values) where T : BaseModel
        {
            values = new List<object>();
            string sql = string.Empty;
            //加载模型类型
            Type type = typeof(T);
            //获取类型的属性 TableName 
            string tableName = Activator.CreateInstance<T>().GetModelDisplayValue();
            List<string> columns = new List<string>();
            string condition = string.Empty;
            object pkValue = default(object);
            //获取类型的所有字段，库对应的所有字段
            PropertyInfo[] propertys = type.GetProperties();
            foreach (PropertyInfo property in propertys)
            {
                if (property.IsDefined(typeof(ModelBaseValidateAttribute), true))
                {
                    ModelBaseValidateAttribute modelAttr = property.GetCustomAttribute<ModelBaseValidateAttribute>();
                    if (!modelAttr.Ignored && !modelAttr.IsPrimaryKey)//如果不存到数据库或者是主键，将不处理
                    {
                        string name = property.GetMemberInfoDisplayValue();
                        //获取传进的值 
                        var propertyValue = property.GetValue(t);
                        values.Add(propertyValue);
                        columns.Add("[" + name + "]=@" + (columns.Count + 1));
                    }
                    if (modelAttr.IsPrimaryKey)//如果是主键，将作为条件过滤
                    {
                        string name = property.GetMemberInfoDisplayValue();
                        condition = "[" + name + "]=";
                        //获取传进的值 
                        var propertyValue = property.GetValue(t);
                        pkValue = propertyValue;
                    }
                }
                else
                {
                    //获取传进的值
                    var propertyValue = property.GetValue(t);
                    columns.Add("[" + property.Name + "]=@" + (columns.Count + 1));
                    values.Add(propertyValue);
                }
            }
            condition += "@" + (columns.Count + 1);
            values.Add(pkValue);
            sql = string.Format("UPDATE [dbo].[{0}] SET {1} WHERE {2}", tableName, string.Join(",", columns.ToArray()), condition);
            return sql;
        }

        /// <summary>
        /// 拼装插入数据的SQL，参数化方式
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        private static string InitInsertSqlByT<T>(T t, out List<object> values) where T : BaseModel
        {
            values = new List<object>();
            List<string> sqlparams = new List<string>();
            string sql = string.Empty;
            //加载模型类型
            Type type = typeof(T);
            //获取类型的属性 TableName 
            string tableName = Activator.CreateInstance<T>().GetModelDisplayValue();
            List<string> columns = new List<string>();
            //获取类型的所有字段，库对应的所有字段
            PropertyInfo[] propertys = type.GetProperties();
            foreach (PropertyInfo property in propertys)
            {
                if (property.IsDefined(typeof(ModelBaseValidateAttribute), true))
                {
                    ModelBaseValidateAttribute modelAttr = property.GetCustomAttribute<ModelBaseValidateAttribute>();
                    if (!modelAttr.Ignored && !modelAttr.IsPrimaryKey)//如果不存到数据库或者是主键，将不处理
                    {
                        string name = property.GetMemberInfoDisplayValue();
                        columns.Add(string.Format("t.[{0}]", name));
                        //获取传进的值
                        var propertyValue = property.GetValue(t);
                        values.Add(propertyValue);
                        sqlparams.Add("@" + values.Count);
                    }
                }
                else
                {
                    columns.Add(string.Format("t.[{0}]", property.Name));
                    //获取传进的值
                    var propertyValue = property.GetValue(t);
                    values.Add(propertyValue);
                    sqlparams.Add("@" + values.Count);
                }
            }
            sql = string.Format("INSERT INTO [dbo].[{0}] ({1}) VALUES ({2}) ", tableName, string.Join(",", columns.ToArray()), string.Join(",", sqlparams.ToArray()));
            return sql;
        }

        /// <summary>
        /// 拼装插入数据的SQL
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        private static string InitInsertSqlByT2<T>(T t) where T : BaseModel
        {
            string sql = string.Empty;
            //加载模型类型
            Type type = typeof(T);
            //获取类型的属性 TableName 
            string tableName = Activator.CreateInstance<T>().GetModelDisplayValue<T>();
            List<string> columns = new List<string>();
            //获取类型的所有字段，库对应的所有字段
            PropertyInfo[] propertys = type.GetProperties();
            List<object> values = new List<object>();
            foreach (PropertyInfo property in propertys)
            {
                if (property.IsDefined(typeof(ModelBaseValidateAttribute), true))
                {
                    ModelBaseValidateAttribute modelAttr = property.GetCustomAttribute<ModelBaseValidateAttribute>();
                    if (!modelAttr.Ignored && !modelAttr.IsPrimaryKey)//如果不存到数据库或者是主键，将不处理
                    {
                        string name = property.GetMemberInfoDisplayValue();
                        columns.Add(string.Format("t.[{0}]", name));
                        //获取传进的值
                        var propertyValue = property.GetValue(t);
                        values.Add(string.Format("'{0}'", propertyValue));
                    }
                }
                else
                {
                    columns.Add(string.Format("t.[{0}]", property.Name));
                    //获取传进的值
                    var propertyValue = property.GetValue(t);
                    values.Add(string.Format("'{0}'", propertyValue));
                }
            }
            sql = string.Format("INSERT INTO [dbo].[{0}] ({1}) VALUES ({2}) ", tableName, string.Join(",", columns.ToArray()), string.Join(",", values.ToArray()));
            return sql;
        }

        /// <summary>
        /// 拼装查询SQL
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        private static string InitSqlByT<T>(bool isQueryAll = true) where T : BaseModel
        {
            string sql = string.Empty;
            //加载模型类型
            Type type = typeof(T);
            //获取类型的属性 TableName 
            string tableName = Activator.CreateInstance<T>().GetModelDisplayValue<T>();
            List<string> columns = new List<string>();
            string condition = string.Empty;
            //获取类型的所有字段，库对应的所有字段
            PropertyInfo[] propertys = type.GetProperties();
            foreach (PropertyInfo property in propertys)
            {
                if (property.IsDefined(typeof(ModelBaseValidateAttribute), true))
                {
                    ModelBaseValidateAttribute modelAttr = property.GetCustomAttribute<ModelBaseValidateAttribute>();
                    if (!modelAttr.Ignored)
                    {
                        string name = property.GetMemberInfoDisplayValue();
                        columns.Add("t." + name);
                    }
                    if (!isQueryAll)
                    {
                        if (modelAttr.IsPrimaryKey)//如果是主键，将作为条件过滤
                        {
                            string name = property.GetMemberInfoDisplayValue();
                            condition = "t.[" + name + "]=@1";
                        }
                    }
                }
                else
                {
                    columns.Add("t." + property.Name);
                }
            }
            if (isQueryAll)
            {
                sql = string.Format("select {0} from [dbo].[{1}] t ", string.Join(",", columns.ToArray()), tableName);
            }
            else
            {
                sql = string.Format("select {0} from [dbo].[{1}] t where {2}", string.Join(",", columns.ToArray()), tableName, condition);
            }
            return sql;
        }
        #endregion

        ///// <summary>
        ///// 获取显示属性值，放到工具类，扩张方法中
        ///// </summary>
        ///// <typeparam name="T"></typeparam>
        ///// <param name="t"></param>
        ///// <returns></returns>
        //private static string GetDisplayValue<T>(T t)
        //{
        //    Type type = typeof(T);

        //    string name = string.Empty;// ((PropertyInfo)t).Name;
        //    PropertyInfo property = null;
        //    //判断传进来的属性还是类
        //    if (type.Name == nameof(PropertyInfo) || type.Name == nameof(FieldInfo))
        //    {
        //        property = t as PropertyInfo;
        //        name = property.Name;
        //    }
        //    else
        //    {
        //        name = type.Name;
        //    }
        //    bool isHaveAttr = false;
        //    if (type.Name == nameof(PropertyInfo))
        //        isHaveAttr = property.IsDefined(typeof(DisplayBaseAttribute), true);
        //    else
        //        isHaveAttr = type.IsDefined(typeof(DisplayBaseAttribute), true);
        //    if (isHaveAttr)
        //    {
        //        object[] attrs;
        //        if (type.Name == nameof(PropertyInfo))
        //            attrs = property.GetCustomAttributes(typeof(DisplayBaseAttribute), false);
        //        else
        //            attrs = type.GetCustomAttributes(typeof(DisplayBaseAttribute), false);
        //        DisplayBaseAttribute attr = (DisplayBaseAttribute)attrs.FirstOrDefault();
        //        if (attr != null)
        //        {
        //            name = attr.Name;
        //        }
        //    }
        //    return name;
        //}

    }
}